home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
awe2-0_1.lha
/
awe2-0.1
/
Src
/
RCS
/
GenericHeap.cc,v
< prev
next >
Wrap
Text File
|
1989-02-20
|
7KB
|
363 lines
head 3.2;
branch ;
access ;
symbols ;
locks ; strict;
comment @@;
3.2
date 89.02.20.15.34.45; author grunwald; state Exp;
branches ;
next 3.1;
3.1
date 88.12.20.13.48.47; author grunwald; state Exp;
branches ;
next 1.2;
1.2
date 88.10.30.13.03.07; author grunwald; state Exp;
branches ;
next 1.1;
1.1
date 88.09.18.16.42.22; author grunwald; state Exp;
branches ;
next ;
desc
@@
3.2
log
@Start using Gnu library heaps for schedulers
@
text
@// This may look like C code, but it is really -*- C++ -*-
//
// Copyright (C) 1988 University of Illinois, Urbana, Illinois
//
// written by Dirk Grunwald (grunwald@@cs.uiuc.edu)
//
#include "Awesime.h"
#include "stream.h"
//
// This defines a Pairing Heap structure for a pointer data type.
//
// See ``The Pairing Heap: A New Form of Self-Adjusting Heap''
// Fredman, Segdewick et al,
// Algorithmica (1986) 1:111-129
//
// In particular, this implements the pairing heap using the circular
// list.
//
//
#ifndef HEAP_INDEX
#define HEAP_INDEX unsigned short
#endif
#ifndef HEAP_INDEX_NULL
#define HEAP_INDEX_NULL 0xffff
#endif
#define NIL GENERIC2(HEAP_NAME,Null)
#define INDEX GENERIC2(HEAP_NAME,Index)
#define ITEM GENERIC2(HEAP_NAME,Item)
#define RECORD GENERIC2(HEAP_NAME,Record)
const INDEX NIL = HEAP_INDEX_NULL;
static const char *GENERIC2(HEAP_NAME,Name) = GENERIC_STRING(HEAP_NAME) ;
HEAP_NAME::HEAP_NAME(int length, bool xdebug)
: (xdebug)
{
freelist = NIL;
allocatedSize = 0;
root = NIL;
elements = 0;
makeRoom(length);
}
INDEX HEAP_NAME::getCell()
{
if (freelist == NIL) {
makeRoom(0);
}
INDEX cell = freelist;
pValid[freelist] = 1;
freelist = storage[freelist].sibling;
elements++;
return(cell);
}
void
HEAP_NAME::returnCell(INDEX cell)
{
storage[cell].sibling = freelist;
pValid[cell] = 0;
freelist = cell;
elements--;
}
void
HEAP_NAME::makeRoom(int atLeast)
{
//
// Out of free space?
//
if (freelist == NIL) {
//
// Is there existing storage?
//
if (allocatedSize > 0) {
//
// Get new storage, copy over existing data & delete old storage
//
INDEX newSize = (allocatedSize * 3) / 2;
RECORD *newStorage = new RECORD[newSize];
char *newValid = new char[newSize];
if (newStorage == 0 || newValid == 0) {
cerr << "[" << GENERIC2(HEAP_NAME,Name) << "::makeRoom] Out of storage space\n";
exit(1);
}
bcopy(storage, newStorage, allocatedSize * sizeof(RECORD));
bcopy(pValid, newValid, allocatedSize * sizeof(char));
delete storage;
delete pValid;
storage = newStorage;
pValid = newValid;
//
// Chain the new stuff into the free list
//
for (int i = allocatedSize; i < newSize; i++) {
storage[i].sibling = i+1;
pValid[i] = 0;
}
storage[newSize-1].sibling = NIL;
freelist = allocatedSize;
allocatedSize = newSize;
} else {
//
// No existing space
//
if (atLeast <= 8) {
allocatedSize = 8;
} else {
allocatedSize = atLeast;
}
storage = new RECORD[allocatedSize];
pValid = new char[allocatedSize];
if (storage == 0) {
cerr << "[" << GENERIC2(HEAP_NAME,Name) << "::getCell] Out of storage\n";
exit(1);
}
for (int i = 0; i < allocatedSize; i++) {
storage[i].sibling = i+1;
pValid[i] = 0;
}
storage[allocatedSize-1].sibling = NIL;
freelist = 0;
}
}
}
//
// makeChild takes two nodes and makes one the child of the other
// and returns the index of the new parent.
//
// We play fast and loose with the siblings field of a & b, although
// we maintain the siblings of the children.
//
INDEX
HEAP_NAME::makeChild(INDEX a, INDEX b)
{
INDEX parent;
INDEX child;
if (storage[a].item <= storage[b].item) {
parent = a; child = b;
} else {
parent = b; child = a;
}
//
// If the new parent has no children, simply add the new child.
// We assume that the child and the parent dont care about
// their *sibling* nodes
//
INDEX popsKid = storage[parent].children;
if (popsKid == NIL) {
storage[parent].children = child;
storage[child].sibling = child;
} else {
INDEX temp = storage[popsKid].sibling;
storage[popsKid].sibling = child;
storage[child].sibling = temp;
storage[parent].children = child;
}
return(parent);
}
void
HEAP_NAME::add(ITEM &item)
{
INDEX cell = getCell();
storage[cell].item = item;
storage[cell].children = NIL;
storage[cell].sibling = NIL;
if (root == NIL) {
root = cell;
} else {
//
// Make cell a child of root. Root may have no kids.
//
root = makeChild(root,cell);
}
}
//
// Item remove is the most complicated routine.
//
// We remove the root (should there be one) and then select a new
// root. The siblings of the root are in a cicular list. We continue
// to pair elements in this list until there is a single element.
// This element will be the new root.
bool
HEAP_NAME::remove(ITEM &removed)
{
bool valid = FALSE;
do {
if (root == NIL || elements <= 0) {
return(0);
}
removed = storage[root].item;
valid = pValid[root];
INDEX child = storage[root].children;
returnCell(root);
if (child == NIL) {
root = NIL;
} else {
while(storage[child].sibling != child) {
//
// We have at least two kids, but we may only have
// two kids. So, oneChild != child, but it is possible
// that twoChild == child.
//
INDEX oneChild = storage[child].sibling;
INDEX twoChild = storage[oneChild].sibling;
//
// Remove the two from the sibling list
//
storage[child].sibling = storage[twoChild].sibling;
storage[oneChild].sibling = NIL;
storage[twoChild].sibling = NIL;
INDEX bestChild = makeChild(oneChild, twoChild);
if (twoChild == child) {
//
// We have reduced the two to one, so we'll be exiting.
//
child = bestChild;
storage[child].sibling = child;
} else {
//
// We've removed two siblings, now we need to insert
// the better of the two
//
storage[bestChild].sibling = storage[child].sibling;
storage[child].sibling = bestChild;
child = storage[bestChild].sibling;
}
}
root = child;
}
} while ( !valid );
return(1);
}
bool
HEAP_NAME::doStart(INDEX &index)
{
for (index = 0; index < allocatedSize; index++) {
if (pValid[index]) {
return(TRUE);
}
}
return(FALSE);
}
bool
HEAP_NAME::doDelete(INDEX &index)
{
if (pValid[index]) {
pValid[index] = FALSE;
elements--;
return(TRUE);
} else {
return( FALSE );
}
}
bool
HEAP_NAME::doNext(INDEX& index)
{
//
// If they are moving on to the next element,
// they are sitting on the current on. So, move to the next
// and then look for a valid one.
//
for (index++; index < allocatedSize; index++) {
if (pValid[index]) {
return(TRUE);
}
}
return(FALSE);
}
void
HEAP_NAME::doDone()
{
//
// Do nothing.
//
}
@
3.1
log
@Steay version
@
text
@@
1.2
log
@*** empty log message ***
@
text
@@
1.1
log
@Initial revision
@
text
@d1 6
@